﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data.Common;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace LinguaHDL
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //form1内全局变量定义
        int n_ouputFileType = 0;
        fileOutPutConfig fileOutCfg = new fileOutPutConfig();
        string last_fileDir = "";
        //Verilog状态机状态定义
        List<string> VerilogFSMState_localparam = new List<string>();
        Form2_ShowFSM form2 = new Form2_ShowFSM();

        public class HDLPortInfo
        {
            public string IODirection;
            public string IOPortName;
            public int     IOPortNameLength;
            public string IOBusPart;
            public string IOBusMSB;
            public string IOBusLSB;
            public bool IOIsBus;
       
        }
        public class fileOutPutConfig
        {
            public bool b_AddModuleOrEntityAndComponent;
            public bool b_AddSignalDefinition;
            public bool b_AddInstantiationTemplate;
            public bool b_InsertSameNameSignal;
            public bool b_AddTestBench;
        
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            checkBox1.Checked = true;
            checkBox2.Checked = true;
            checkBox3.Checked = true;
            checkBox4.Checked = true;
            checkBox5.Checked = true;

            //form2.Show();

           // string ver_line = "		output								sata_core_clk,					// SATA Core Clock, Rising Edge";
           // stringRegulate_vhd(ver_line);
         //   vhdLine2verLine("begin");
           // getEntityName(vhd_list);
           // HDLProcess();
            //string ver_line = "io[12:0]";
            //string ve=ver_line.Substring(ver_line.IndexOf("["), ver_line.IndexOf("]") - ver_line.IndexOf("[") + 1);

         //   ExplorePath("E:\\VSProjects\\VStests\\ddr3_io_csv2xdc\\维护文档\\CSV文件.PNG");
        }

        public static void Explorefile(string filePath)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = "explorer.exe";
          //  proc.StartInfo.Arguments = @"/select, " + filePath;
            proc.Start();
        
        }
        public static void ExplorePath(string filePath)
        {
            System.Diagnostics.Process.Start("explorer.exe", filePath);
        
        }
       
        
        public string HDLineRegulate(string HDlineOriginal, string languageCommentKey)
        {
            string HDline = "";
            //删除注释

            string ver_line_noComment;
            if (HDlineOriginal.Contains(languageCommentKey))
            {
                ver_line_noComment = HDlineOriginal.Substring(0, HDlineOriginal.IndexOf(languageCommentKey));

            }
            else
                ver_line_noComment = HDlineOriginal;


            //删除横向制表符
            HDline = ver_line_noComment.Replace("\t", "");
            //删除所有空格，逗号，分号
            HDline = HDline.Replace(" ", "");
            HDline = HDline.Replace(",", "");
          //  HDline = HDline.Replace(";", "");

            return HDline;
        }
        //verilog输入文本处理，去除注释和非端口定义所需字符"\t"
        //输入：读入的原始行
        //输出：不包含单行注释，以及横向制表符的文本行
  
      
       
        private void button1_Click(object sender, EventArgs e)
        {
            if ( (fileOutCfg.b_AddTestBench == false)&&
                (fileOutCfg.b_AddSignalDefinition == false)&& 
                (fileOutCfg.b_AddInstantiationTemplate == false)&&
                (fileOutCfg.b_AddModuleOrEntityAndComponent== false) )
            {
                MessageBox.Show("请选择至少一个输出项");
                return;
            }
            HDLProcess();
            //MessageBox.Show("输出文件已生成在当前文件夹下");       
        }

        //提供对话框来选择文件
        //输入：可选取的文件后缀过滤参数
        //输出：选择的文件全路径
        public string  openFile(string fileFilter)
        {
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.InitialDirectory = "D://";
            openFile.Filter = fileFilter; 
            // openFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            openFile.Multiselect = false;
            if (openFile.ShowDialog() == DialogResult.Cancel) return "err";
            var filePath = openFile.FileName;

            string fileType = System.IO.Path.GetExtension(filePath);
            if (string.IsNullOrEmpty(fileType)) return "err";
            FileInfo fileinfo = new FileInfo(openFile.SafeFileName);
            //在此处添加后续操作

            return filePath;

        }
        public string openFile(string fileFilter, out string fileExtensionType)
        {
            OpenFileDialog openFile = new OpenFileDialog();
           // openFile.InitialDirectory = "F://";
            openFile.Filter = fileFilter;
            
            // openFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            openFile.Multiselect = false;
            fileExtensionType = null;
            if (openFile.ShowDialog() == DialogResult.Cancel) return "err";
            var filePath = openFile.FileName;

            string fileType = System.IO.Path.GetExtension(filePath);
            if (string.IsNullOrEmpty(fileType)) return "err";
            FileInfo fileinfo = new FileInfo(openFile.SafeFileName);
            //在此处添加后续操作
            fileExtensionType = fileType;
            return filePath;

        }
        public List<string> vhGetPortDecalration(List<string> vhOriginalList)
        {
            List<string> reguList = new List<string>();
            List<string> onlyPortDef = new List<string>();

            foreach (string vh_line in vhOriginalList)
            {
                string vh_lineRegu = HDLineRegulate(vh_line, "--");

                if (vh_lineRegu!="") reguList.Add(vh_lineRegu);
            }
            //提取entity定义
            bool startEttyCapted = false;
            bool endEttyCapted = false;
            string ettyStrSum = null;
            foreach (string vh_line in reguList)
            {
                if (startEttyCapted == false)
                {
                    string vh_line_lower = vh_line.ToLower();
                    if (vh_line_lower.IndexOf("entity") == 0)
                    {
                        startEttyCapted = true;
                        onlyPortDef.Add(vh_line);
                        ettyStrSum += vh_line.ToLower();
                    }
                }
                else if (endEttyCapted == false)
               {
                   if (ettyStrSum.Contains("c);") || ettyStrSum.Contains("));"))
                    {
                        endEttyCapted = true;
                        onlyPortDef.Add(vh_line);
                        ettyStrSum += vh_line.ToLower();
                    }
                    else
                    {
                        onlyPortDef.Add(vh_line);
                        ettyStrSum += vh_line.ToLower();
                    }
                    
               }
                
                

            }

            return onlyPortDef;
        }
        //将目标文件按行装载在list中
        //输入：目标文件全路径
        //输出：包含文件所有内容的list<string>
        public List<string> loadFile(string filePath)
        {
            List<string> list_str = new List<string>();
            FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);

            //StreamReader sr = new StreamReader(fs, Encoding.UTF8);
            StreamReader sr = new StreamReader(fs, Encoding.Default);

            //记录每次读取的一行记录
            string strLine = "";
            while ((strLine = sr.ReadLine()) != null)
            {
                list_str.Add(strLine);
            }
            sr.Close();
            fs.Close();
            return list_str;

        }
        //获取vhdl实体名称
        //输入：包含vhdl文件内容的list<string>
        //输出：实体名称
        public string getEntityName(List<string> vhdl_line_list)
        {
            //返回值定义
            string entityName = "err";

            foreach (string vhd_line in vhdl_line_list)
            {
                //字符预处理
                string vhd_lineRegu;
                vhd_lineRegu = vhd_line.Replace(" ", ""); //删除空格
                //entity 和entity name需要在同一行，符合一般习惯，其余情况暂不考虑
                if (vhd_lineRegu.IndexOf("entity") == 0 || vhd_lineRegu.IndexOf("ENTITY") == 0)
                {
                    if (vhd_lineRegu.Contains("is"))
                    {
                        entityName = vhd_lineRegu.Substring(6, vhd_lineRegu.IndexOf("is") - 6);
                        break;

                    }
                    else  if (vhd_lineRegu.Contains("IS"))
                    {
                            entityName = vhd_lineRegu.Substring(6, vhd_lineRegu.IndexOf("IS") - 6);
                            break;

                    }
                    else
                    {
                        entityName = vhd_lineRegu.Substring(6);
                        break;
                    }

                }


            }



            return entityName;
        
        }
        //获取verilog模块名称
        //输入：包含verilog文件内容的list<string>
        //输出：模块名称
        public string getModuleName(List<string> list_str)
        {
            //返回值定义
            string moduleName = "err";

            foreach (string ver_line in list_str)
            {
                //字符预处理
                string ver_lineRegu;
                ver_lineRegu = ver_line.Replace(" ", ""); //删除空格
                //module 和module name需要在同一行，符合一般习惯，其余情况暂不考虑
                if (ver_lineRegu.IndexOf("module") == 0)
                {
                    if (ver_lineRegu.Contains("("))
                    {
                        moduleName = ver_lineRegu.Substring(6, ver_lineRegu.IndexOf("(") - 6);
                        break;

                    }
                    else
                    {
                        moduleName = ver_lineRegu.Substring(6);
                        break;
                    }

                }


            }



            return moduleName;
        }
    

        private void 功能ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("可以根据符合规范的verilog,vhdl端口定义，生成包括module/entity，component，例化模板，信号定义，以及TB部分语句块模板");
        }

        private void 版本ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("当前版本v0.01，更新日期2017.9.29");
        }
        //选择HDL端口定义文件生成verilog语言的辅助文件
        private void button2_Click(object sender, EventArgs e)
        {
            
            
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            if (!((RadioButton)sender).Checked)
            {
                return;
            }
            switch (((RadioButton)sender).Text.ToString())
            {
                case "输出为Verilog格式": n_ouputFileType = 0;
                    break;
                case "输出为VHDL格式": n_ouputFileType = 1;
                    break;
               
                default: n_ouputFileType = 0;
                    break;
            
            }
        }
        //基于datatable的主流程
        public void HDLProcess()
        {
            string fileFilter = "Verilog Flile(*.v)|*.v|VHDL Flile(*.vhd)|*.vhd";
            string fileType;
            string filePath = openFile(fileFilter,out fileType);
            if (filePath == "err") return;

            List<string> list_str = new List<string>();
            list_str = loadFile(filePath);
            textBox1_fileDir.Text = System.IO.Path.GetDirectoryName(filePath);
            //判断语言类型
            string languageCommentKey;
            if (fileType == ".v")
            {
                //进行Verilog关键信息提取
                languageCommentKey = "//";
                verilogPortDefinitionProcess(list_str, languageCommentKey, filePath);
            }
            else if (fileType == ".vhd")
            {
                //进行VHDL关键信息提取
                languageCommentKey = "--";
                vhdlPortDefinitionProcess(list_str, languageCommentKey, filePath);
            }
            else
            {
                MessageBox.Show("文件类型不正确！处理过程终止");
                return; 
            }
           // ExplorePath(System.IO.Path.GetDirectoryName(filePath));
            last_fileDir = System.IO.Path.GetDirectoryName(filePath);
        }
        //verilog 处理过程
        public void verilogPortDefinitionProcess(List<string> verilogLineList, string languageCommentKey, string filePath)
        { 
            //建立datatable
            DataTable verilogPortInfoTable = createPortInfoDataTable();           
            //获取到模块名称
            string moduleName = getModuleName(verilogLineList);            
            //提取端口信息
            int n_nameLenMax = 0;
            int n_BusPartLenMax = 0;
            foreach (string ver_line in verilogLineList)
            {
                //剔除多余字符
                string verLineRegulated = HDLineRegulate(ver_line, languageCommentKey);
                //判断IO方向
                int n_IODirectionLen;
                string s_IODirection;
                HDLPortInfo verPortInfo = new HDLPortInfo();
                
                if (verLineRegulated.Contains("input"))
                {
                    n_IODirectionLen = 5;
                    s_IODirection = "input";
                }
                else if (verLineRegulated.Contains("output"))
                {
                    n_IODirectionLen = 6;
                    s_IODirection = "output";

                }
                else if (verLineRegulated.Contains("inout"))
                {
                    n_IODirectionLen = 5;
                    s_IODirection = "inout";
                }

                else
                {
                    n_IODirectionLen = -1;
                    s_IODirection = "err";

                }
                verPortInfo.IODirection = s_IODirection;//保存IO方向定义
                if (s_IODirection != "err" && n_IODirectionLen > 0)
                {
                    //判断是否多位宽
                    if (verLineRegulated.Contains("["))
                    {
                        int colonIndex = verLineRegulated.IndexOf(":");
                        int leftBrkIndex = verLineRegulated.IndexOf("[");
                        int rightBrkIndex = verLineRegulated.IndexOf("]");
                        //取出bus信息
                        verPortInfo.IOBusPart = verLineRegulated.Substring(leftBrkIndex,
                                                                    rightBrkIndex - leftBrkIndex + 1);
                        verPortInfo.IOBusMSB = verLineRegulated.Substring(leftBrkIndex + 1, colonIndex - leftBrkIndex-1);
                        verPortInfo.IOBusLSB = verLineRegulated.Substring(colonIndex + 1, rightBrkIndex - colonIndex-1);
                        verPortInfo.IOIsBus = true;
                        //取出端口名称

                        string portNameOrg = verLineRegulated.Substring(rightBrkIndex + 1);
                        verPortInfo.IOPortName = portNameOrg.Replace(";", "");
                        
                        verPortInfo.IOPortNameLength = verPortInfo.IOPortName.Length;

                    }
                    else
                    { 
                        //只需取出端口名称
                        int n_ioIndex = verLineRegulated.IndexOf(s_IODirection);
                        string portNameOrg = verLineRegulated.Substring(n_ioIndex + n_IODirectionLen);
                        verPortInfo.IOPortName = portNameOrg.Replace(";","");
                        verPortInfo.IOPortNameLength = verPortInfo.IOPortName.Length;
                        //设置bus信息
                        verPortInfo.IOIsBus = false;
                        verPortInfo.IOBusMSB = null;
                        verPortInfo.IOBusLSB = null;
                    }

                    //将端口信息装入datatable
                    DataRow dr = verilogPortInfoTable.NewRow();
                    dr[0] = verPortInfo.IODirection;
                    dr[1] = verPortInfo.IOPortName;
                    dr[2] = verPortInfo.IOPortNameLength;
                    dr[3] = verPortInfo.IOBusPart;
                    dr[4] = verPortInfo.IOBusMSB;
                    dr[5] = verPortInfo.IOBusLSB;
                    dr[6] = verPortInfo.IOIsBus;
                    verilogPortInfoTable.Rows.Add(dr);
                    //计算端口字符最大长度
                    if (n_nameLenMax < verPortInfo.IOPortNameLength) n_nameLenMax = verPortInfo.IOPortNameLength;
                    if (verPortInfo.IOBusPart != null)
                    {
                        if (n_BusPartLenMax < verPortInfo.IOBusPart.Length) n_BusPartLenMax = verPortInfo.IOBusPart.Length;
                    }
                }
            }// end foreach
          
            //关键信息提取完毕，可进行后续操作
            //判断输出文件类型
            if (n_ouputFileType == 0) //verilog输出
            { 
                //创建文件
                FileStream fs = createOutputHDLTemplateFile(filePath, "v");
                StreamWriter sw = new StreamWriter(fs); // 创建写入流
                //将语句写入文件
                if(fileOutCfg.b_AddModuleOrEntityAndComponent)  
                    verilogWriteModule(sw, verilogPortInfoTable, moduleName, n_BusPartLenMax);
                if (fileOutCfg.b_AddSignalDefinition ) 
                    verilogWriteSignal(sw, verilogPortInfoTable, n_BusPartLenMax);
                //设置需要连线
                bool b_AddConnection = false;
                if(fileOutCfg.b_AddInstantiationTemplate)
                    verilogWriteInstantiationTemplate(sw, verilogPortInfoTable, moduleName, fileOutCfg.b_InsertSameNameSignal , n_nameLenMax);
                if (fileOutCfg.b_AddTestBench)
                    verilogWriteClockGenAndInitialBlkForTB(sw, verilogPortInfoTable);
                //PortInfoTableTanslate(verilogPortInfoTable, "vhd");
                sw.Close();
                fs.Close();
                //写入
            }
            else if (n_ouputFileType == 1) //vhdl输出
            { 
                //创建vhdl格式的datatable，翻译本地已有datatable，将信息导入新的datatable
                DataTable vhdlPortInfoTable = createPortInfoDataTable();
                vhdlPortInfoTable = PortInfoTableTanslate(verilogPortInfoTable, "vhd");
                //创建文件
                FileStream fs = createOutputHDLTemplateFile(filePath, "vhd");
                StreamWriter sw = new StreamWriter(fs); // 创建写入流
                //将语句写入文件
                if (fileOutCfg.b_AddModuleOrEntityAndComponent)
                {
                    vhdlWriteEntity(sw, vhdlPortInfoTable, moduleName, n_nameLenMax);
                    vhdlWriteComponent(sw, vhdlPortInfoTable, moduleName, n_nameLenMax);
                }
                if (fileOutCfg.b_AddSignalDefinition) 
                    vhdlWriteSignal(sw, vhdlPortInfoTable, n_nameLenMax);
                if (fileOutCfg.b_AddInstantiationTemplate)
                    vhdlWriteInstantiationTemplate(sw, vhdlPortInfoTable, moduleName, fileOutCfg.b_InsertSameNameSignal, n_nameLenMax);
                if (fileOutCfg.b_AddTestBench)
                    vhdlWriteTestBench(sw);
                sw.Close();
                fs.Close();
            }
            else
            { }

        
        }
        //vhdl处理过程
        public void vhdlPortDefinitionProcess(List<string> vhdlLineList, string languageCommentKey, string filePath)
        {
            //建立datatable
            DataTable vhdlPortInfoTable = createPortInfoDataTable();
            //获取到模块名称
            string entityName = getEntityName(vhdlLineList);
            //过滤环节
            List<string> vhdPortLineList = new List<string>();
            vhdPortLineList = vhGetPortDecalration(vhdlLineList);
            //提取端口信息
            int n_nameLenMax = 0;
            int n_BusPartLenMax = 0;
            foreach (string vhd_line in vhdPortLineList)
            {
                //剔除多余字符
                string vhdLineRegulated = HDLineRegulate(vhd_line, languageCommentKey);
                //判断IO方向
                
                string s_IODirection;
                string vhd_line_lower = vhdLineRegulated.ToLower();
                HDLPortInfo vhdPortInfo = new HDLPortInfo();
                if (vhd_line_lower.Contains(":"))
                { 
                    if(vhd_line_lower.Contains("std_logic"))
                    {
                        if (vhd_line_lower.IndexOf("port(")==0)//行首多余port加左括号
                        {
                            
                            vhdPortInfo.IOPortName = vhdLineRegulated.Substring(5, vhdLineRegulated.IndexOf(":")-5);
                            vhdPortInfo.IOPortNameLength = vhdPortInfo.IOPortName.Length;

                            
                        }
                        else if (vhd_line_lower.IndexOf("(")==0) //行首多余左括号
                        {
                            vhdPortInfo.IOPortName = vhdLineRegulated.Substring(1, vhdLineRegulated.IndexOf(":")-1);
                            vhdPortInfo.IOPortNameLength = vhdPortInfo.IOPortName.Length;

                            

                        }
                        else  //规范情况
                        {
                            
                            vhdPortInfo.IOPortName = vhdLineRegulated.Substring(0, vhdLineRegulated.IndexOf(":"));
                            vhdPortInfo.IOPortNameLength = vhdPortInfo.IOPortName.Length;

                            
                        }
                        s_IODirection = vhd_line_lower.Substring(vhd_line_lower.IndexOf(":") + 1, vhd_line_lower.IndexOf("std_logic") - vhd_line_lower.IndexOf(":")-1);
                    }
                    else
                    {
                    
                    s_IODirection = "err";
                    
                    }
                
                }
                else s_IODirection = "err";
                    
                vhdPortInfo.IODirection = s_IODirection;//保存IO方向定义
                if (s_IODirection != "err")
                {
                    //判断是否多位宽
                    if (vhd_line_lower.Contains("std_logic_vector"))
                    {
                        string busMSB;
                        string busLSB;
                        int leftBracketIndex = vhd_line_lower.IndexOf("(");

                        string busInfoPart = vhdLineRegulated.Substring(leftBracketIndex);
                        int rightBracketIndex_offset = busInfoPart.IndexOf(")");
                        vhdPortInfo.IOBusPart = busInfoPart.Replace(";",""); //去掉分号
                        //取出msb，lsb
                        bool b_msbLSBErrFlag = false;
                        if (busInfoPart.Contains("downto"))
                        {
                            vhdPortInfo.IOIsBus = true;
                            vhdPortInfo.IOBusMSB = busInfoPart.Substring(1, busInfoPart.IndexOf("downto") - 1);
                            vhdPortInfo.IOBusLSB = busInfoPart.Substring(busInfoPart.IndexOf("downto") + 6, rightBracketIndex_offset - (busInfoPart.IndexOf("downto") + 6));
                        }
                        else if (busInfoPart.Contains("to"))
                        {
                            int dbg_ind = busInfoPart.IndexOf("to");
                            vhdPortInfo.IOIsBus = true;
                            vhdPortInfo.IOBusMSB = busInfoPart.Substring(1, busInfoPart.IndexOf("to") - 1);
                            vhdPortInfo.IOBusLSB = busInfoPart.Substring(busInfoPart.IndexOf("to") + 2, rightBracketIndex_offset - (busInfoPart.IndexOf("to") + 2));
                        }
                        else
                        {
                            b_msbLSBErrFlag = true;
                            MessageBox.Show("std_logic_vector信息错误，请核对输入文件！");
                            return;
                        }
                        
                    
                    }
                    else if (vhd_line_lower.Contains("std_logic"))
                    {
                        vhdPortInfo.IOIsBus = false;
                        vhdPortInfo.IOBusMSB = null;
                        vhdPortInfo.IOBusLSB = null;
                    }
                    //将端口信息装入datatable
                    DataRow dr = vhdlPortInfoTable.NewRow();
                    dr[0] = vhdPortInfo.IODirection;
                    dr[1] = vhdPortInfo.IOPortName;
                    dr[2] = vhdPortInfo.IOPortNameLength;
                    dr[3] = vhdPortInfo.IOBusPart;
                    dr[4] = vhdPortInfo.IOBusMSB;
                    dr[5] = vhdPortInfo.IOBusLSB;
                    dr[6] = vhdPortInfo.IOIsBus;
                    vhdlPortInfoTable.Rows.Add(dr);
                    //计算端口字符最大长度
                    if (n_nameLenMax < vhdPortInfo.IOPortNameLength) n_nameLenMax = vhdPortInfo.IOPortNameLength;
                    if (vhdPortInfo.IOBusPart != null)
                    {
                        if (n_BusPartLenMax < vhdPortInfo.IOBusPart.Length) n_BusPartLenMax = vhdPortInfo.IOBusPart.Length;
                    }


                }
            
            }//end foreach

            //关键信息提取完毕，可进行后续操作
            //判断输出文件类型
            if (n_ouputFileType == 0) //verilog输出
            {
                //创建verilog格式的datatable，翻译本地已有datatable，将信息导入新的datatable
                DataTable verilogPortInfoTable = createPortInfoDataTable();
                verilogPortInfoTable = PortInfoTableTanslate(vhdlPortInfoTable, "v");
                //创建文件
                FileStream fs = createOutputHDLTemplateFile(filePath, "v");
                StreamWriter sw = new StreamWriter(fs); // 创建写入流
                //将语句写入文件
                if (fileOutCfg.b_AddModuleOrEntityAndComponent)
                    verilogWriteModule(sw, verilogPortInfoTable, entityName, n_BusPartLenMax);
                if (fileOutCfg.b_AddSignalDefinition)
                    verilogWriteSignal(sw, verilogPortInfoTable, n_BusPartLenMax);
                //设置需要连线
                bool b_AddConnection = false;
                if (fileOutCfg.b_AddInstantiationTemplate)
                    verilogWriteInstantiationTemplate(sw, verilogPortInfoTable, entityName, fileOutCfg.b_InsertSameNameSignal, n_nameLenMax);
                if (fileOutCfg.b_AddTestBench)
                    verilogWriteClockGenAndInitialBlkForTB(sw, verilogPortInfoTable);
                //PortInfoTableTanslate(verilogPortInfoTable, "vhd");
                sw.Close();
                fs.Close();
                //写入
            }
            else if (n_ouputFileType == 1) //vhdl输出
            {
                
                //创建文件
                FileStream fs = createOutputHDLTemplateFile(filePath, "vhd");
                StreamWriter sw = new StreamWriter(fs); // 创建写入流
                //将语句写入文件
                if (fileOutCfg.b_AddModuleOrEntityAndComponent)
                {
                    vhdlWriteEntity(sw, vhdlPortInfoTable, entityName, n_nameLenMax);
                    vhdlWriteComponent(sw, vhdlPortInfoTable, entityName, n_nameLenMax);
                }
                if (fileOutCfg.b_AddSignalDefinition)
                    vhdlWriteSignal(sw, vhdlPortInfoTable, n_nameLenMax);
                if(fileOutCfg.b_AddInstantiationTemplate)
                    vhdlWriteInstantiationTemplate(sw, vhdlPortInfoTable, entityName, fileOutCfg.b_InsertSameNameSignal, n_nameLenMax);
                if (fileOutCfg.b_AddTestBench)
                    vhdlWriteTestBench(sw);
                sw.Close();
                fs.Close();
            }
            else
            { }
        
        }
        //核心datatable创建
        public DataTable createPortInfoDataTable()
        {
            DataTable PortInfoTable = new DataTable();

            DataColumn IODirection = new DataColumn("IODirection");
            DataColumn IOPortName = new DataColumn("IOPortName");
            DataColumn IOPortNameLength = new DataColumn("IOPortNameLength");
            DataColumn IOBusPart = new DataColumn("IOBusPart");
            DataColumn IOBusMSB = new DataColumn("IOBusMSB");
            DataColumn IOBusLSB = new DataColumn("IOBusLSB");
            DataColumn IOIsBus = new DataColumn("IOIsBus");

            IODirection.DataType = Type.GetType("System.String");
            IOPortName.DataType = Type.GetType("System.String");
            IOPortNameLength.DataType = Type.GetType("System.Int32");
            IOBusPart.DataType = Type.GetType("System.String");
            IOBusMSB.DataType = Type.GetType("System.String");
            IOBusLSB.DataType = Type.GetType("System.String");
            IOIsBus.DataType = Type.GetType("System.Boolean");

            PortInfoTable.Columns.Add(IODirection);
            PortInfoTable.Columns.Add(IOPortName);
            PortInfoTable.Columns.Add(IOPortNameLength);
            PortInfoTable.Columns.Add(IOBusPart);
            PortInfoTable.Columns.Add(IOBusMSB);
            PortInfoTable.Columns.Add(IOBusLSB);
            PortInfoTable.Columns.Add(IOIsBus);

            return PortInfoTable;
        
        }
        //在文件的同一目录下创建输出文件，返回文件流
        public FileStream createOutputHDLTemplateFile(string filePath, string fileType)
        {
            string fileDir = System.IO.Path.GetDirectoryName(filePath);
            string fileNameNoSuffix = System.IO.Path.GetFileNameWithoutExtension(filePath);
            FileStream fs = new FileStream(fileDir + "\\" + fileNameNoSuffix + "_Template" + "." +fileType, FileMode.Create, FileAccess.ReadWrite);
            label1_fileName.Text = fileNameNoSuffix + "_Template" + "." + fileType;
            return fs;
        
        }
        //datatable转换，调用时注意目的类型不能有错
        //输入：源datatable，目的datatable类型
        //输出：目的datatable
        public DataTable PortInfoTableTanslate(DataTable src_dataTable, string dst_type)
        {
            DataTable dst_dataTable = createPortInfoDataTable();
            if (dst_type == "v")
            { 
                //从vhdl格式转换为verilog格式
                HDLPortInfo dst_PortInfo = new HDLPortInfo();
                foreach (DataRow dr in src_dataTable.Rows)
                { 
                    //方向
                    switch (dr["IODirection"].ToString().ToLower())
                    {
                        case "in": dst_PortInfo.IODirection = "input";
                            break;
                        case "inout": dst_PortInfo.IODirection = "inout";
                            break;
                        case "out": dst_PortInfo.IODirection = "output";
                            break;
                    }
                    //端口名
                    dst_PortInfo.IOPortName = dr["IOPortName"].ToString();
                    //端口名称长度
                    dst_PortInfo.IOPortNameLength = (int)dr["IOPortNameLength"];
                    //总线信息
                    if ((bool)dr["IOIsBus"] == false)
                    {
                        dst_PortInfo.IOBusPart = null;
                        dst_PortInfo.IOBusMSB = null;
                        dst_PortInfo.IOBusLSB = null;
                        dst_PortInfo.IOIsBus = false;

                    }
                    else
                    {
                        //组合总线部分
                        dst_PortInfo.IOBusPart = "[" + dr["IOBusMSB"].ToString() + ":" + dr["IOBusLSB"].ToString() + "]";
                        
                        dst_PortInfo.IOBusMSB = dr["IOBusMSB"].ToString();
                        dst_PortInfo.IOBusLSB = dr["IOBusLSB"].ToString();
                        dst_PortInfo.IOIsBus = true;
                    }

                    DataRow ndr = dst_dataTable.NewRow();
                    ndr[0] = dst_PortInfo.IODirection;
                    ndr[1] = dst_PortInfo.IOPortName;
                    ndr[2] = dst_PortInfo.IOPortNameLength;
                    ndr[3] = dst_PortInfo.IOBusPart;
                    ndr[4] = dst_PortInfo.IOBusMSB;
                    ndr[5] = dst_PortInfo.IOBusLSB;
                    ndr[6] = dst_PortInfo.IOIsBus;
                    dst_dataTable.Rows.Add(ndr);

                }
                
            }
            else if (dst_type == "vhd")
            {
                //从verilog格式转换为vhdl格式
                HDLPortInfo dst_PortInfo = new HDLPortInfo();
                foreach (DataRow dr in src_dataTable.Rows)
                {
                    //方向
                    switch (dr["IODirection"].ToString().ToLower())
                    {
                        case "input": dst_PortInfo.IODirection = "in";
                            break;
                        case "inout": dst_PortInfo.IODirection = "inout";
                            break;
                        case "output": dst_PortInfo.IODirection = "out";
                            break;
                    }
                    //端口名
                    dst_PortInfo.IOPortName = dr["IOPortName"].ToString();
                    //端口名称长度
                    dst_PortInfo.IOPortNameLength = (int)dr["IOPortNameLength"];
                    //总线信息
                    if ((bool)dr["IOIsBus"] == false)
                    {
                        dst_PortInfo.IOBusPart = null;
                        dst_PortInfo.IOBusMSB = null;
                        dst_PortInfo.IOBusLSB = null;
                        dst_PortInfo.IOIsBus = false;

                    }
                    else
                    {
                        //downto/to选择
                        if (dr["IOBusLSB"].ToString() == "0") dst_PortInfo.IOBusPart = "std_logic_vector" + "(" + dr["IOBusMSB"].ToString() + " downto " + dr["IOBusLSB"].ToString() + ")";
                        else dst_PortInfo.IOBusPart = "std_logic_vector" + "(" + dr["IOBusMSB"].ToString() + " to " + dr["IOBusLSB"].ToString() + ")";
                        dst_PortInfo.IOBusMSB = dr["IOBusMSB"].ToString();
                        dst_PortInfo.IOBusLSB = dr["IOBusLSB"].ToString();
                        dst_PortInfo.IOIsBus = true;
                    }

                    DataRow ndr = dst_dataTable.NewRow();
                    ndr[0] = dst_PortInfo.IODirection;
                    ndr[1] = dst_PortInfo.IOPortName;
                    ndr[2] = dst_PortInfo.IOPortNameLength;
                    ndr[3] = dst_PortInfo.IOBusPart;
                    ndr[4] = dst_PortInfo.IOBusMSB;
                    ndr[5] = dst_PortInfo.IOBusLSB;
                    ndr[6] = dst_PortInfo.IOIsBus;
                    dst_dataTable.Rows.Add(ndr);

                }
            }

            
            
            
            return dst_dataTable;
        }
        //定义Verilog的过程单元
        //1.写入module
        //2.写入信号定义
        //3.写入例化模板，可选择是否连接引脚
        //4.写入tb

        //1.写入module
        public int verilogWriteModule(StreamWriter sw, DataTable verilogPortInfoTable, string moduleName, int n_BusPartLenMax)
        {
            sw.WriteLine("//Definition of module");
            //按格式写入module
            //写入module关键字 行
            sw.WriteLine("module " + moduleName + " (");
            int wr_cnt = 0;
            foreach (DataRow dr in verilogPortInfoTable.Rows)
            {
                wr_cnt = wr_cnt + 1;
                sw.Write("\t");
                sw.Write(dr["IODirection"]);
                int n_spaceNeedCount;
                if (dr["IODirection"].ToString() == "output") n_spaceNeedCount = 5;
                else n_spaceNeedCount = 6;
                //添加空格以对齐
                for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                //判断是否需要写入位宽信息
               // string isbus = dr["IOIsBus"].ToString();
               // Boolean isbusb = (Boolean)dr["IOIsBus"];
                if ((Boolean)dr["IOIsBus"])
                {
                    sw.Write(dr["IOBusPart"]);
                    for (int spcCnt = 0; spcCnt < (n_BusPartLenMax - dr["IOBusPart"].ToString().Length); spcCnt++) sw.Write(" ");
                }
                //添加空格以对齐
                else for (int spcCnt = 0; spcCnt < n_BusPartLenMax; spcCnt++) sw.Write(" ");
                for (int spcCnt = 0; spcCnt < 6; spcCnt++) sw.Write(" ");
                //写入端口名称
                sw.Write(dr["IOPortName"]);
                //除最后一行外都加入逗号
                if (wr_cnt < verilogPortInfoTable.Rows.Count) sw.Write(",");
                //换行
                sw.Write("\n");

            }
            //写入终止括号行
            sw.WriteLine(");");
            //写入endmodule关键字行
            sw.WriteLine("endmodule");
            sw.WriteLine("");
            return 0;
        }
        //2.写入信号定义
        public int verilogWriteSignal(StreamWriter sw, DataTable verilogPortInfoTable, int n_BusPartLenMax)
        {
            sw.WriteLine("//Definition for signals");
            foreach (DataRow dr in verilogPortInfoTable.Rows)
            {
                
                sw.Write("\t");
                //具有out属性的都使用wire，其他情况使用reg
                if (dr["IODirection"].ToString().Contains("out")) sw.Write("wire   ");
                else sw.Write("reg    ");
                
                //判断是否需要写入位宽信息               
                if ((Boolean)dr["IOIsBus"])
                {
                    sw.Write(dr["IOBusPart"]);
                    for (int spcCnt = 0; spcCnt < (n_BusPartLenMax - dr["IOBusPart"].ToString().Length); spcCnt++) sw.Write(" ");
                }
                //添加空格以对齐
                else for (int spcCnt = 0; spcCnt < n_BusPartLenMax; spcCnt++) sw.Write(" ");
                for (int spcCnt = 0; spcCnt < 4; spcCnt++) sw.Write(" ");
                //写入端口名称
                sw.Write(dr["IOPortName"]+";");
               
                //换行
                sw.Write("\n");

            }
            sw.Write("\n");
            return 0;
        }
        //3.写入例化模板，可选择是否连接引脚
        public int verilogWriteInstantiationTemplate(StreamWriter sw, DataTable verilogPortInfoTable,string moduleName, bool b_AddConnection, int n_nameLenMax)
        {
            sw.WriteLine("//Instantiation Template");
            int wr_cnt = 0;
            sw.WriteLine(moduleName + " my_inst_name " + "(");
            foreach (DataRow dr in verilogPortInfoTable.Rows)
            {
                //计算每行填入的空格数
                int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);
                
                wr_cnt = wr_cnt + 1;
                sw.Write("\t");
                //写入端口名
                sw.Write("."+dr["IOPortName"]);
                //写入空格
                for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                //写入连接
                if (b_AddConnection) sw.Write("(" + dr["IOPortName"] + ")");
                else sw.Write("( )");
                    
                //写入逗号
                if (wr_cnt < verilogPortInfoTable.Rows.Count) sw.Write(",");
                //写入方向注释
                sw.Write("  //" + dr["IODirection"].ToString());
                if ((Boolean)dr["IOIsBus"]) sw.Write(" "+dr["IOBusPart"]);
                //换行
                sw.Write("\n");

            }
            sw.WriteLine(");");
            return 0;
        }
        //4.写入tb中的时钟产生和初始化模块
        public int verilogWriteClockGenAndInitialBlkForTB(StreamWriter sw, DataTable verilogPortInfoTable)
        {
            //尝试寻找时钟信号
            List<string> clkList=new List<string>();
            foreach (DataRow dr in verilogPortInfoTable.Rows)
            {
                string portName = dr["IOPortName"].ToString();
                string portName_lower = portName.ToLower();
                if (portName_lower.Contains("clk"))
                {
                    clkList.Add(portName);
                
                }
            
            }
            //写入时钟生成部分
            foreach (string clkName in clkList)
            {
                sw.WriteLine("always #10  " + clkName + " = ~" + clkName+";");
            
            }
            //写入初始化
            sw.Write("\n");
            sw.WriteLine("initial begin");
            foreach (string clkName in clkList)
            {
                sw.WriteLine(clkName + " = 0;");
            }
            sw.WriteLine("");
            sw.WriteLine("");
            sw.WriteLine("");

            sw.WriteLine("end");
            return 0;
        }
        //定义vhdl的过程单元
        //1.写入entity
        //2.写入component
        //3.写入信号定义
        //4.写入例化模板，可选择是否连接引脚
        //5.写入tb

        //1.写入entity
        public int vhdlWriteEntity(StreamWriter sw, DataTable vhdlPortInfoTable, string entityName, int n_nameLenMax)
        {
            sw.WriteLine("--Definition of entity");
            //写入entity，port关键字 行
            sw.WriteLine("entity " + entityName + " is");
            sw.WriteLine("port (");
            int wr_cnt = 0;
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                //计算每行填入的空格数
                int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);
                
                wr_cnt = wr_cnt + 1;
                sw.Write("\t");
                //写入端口名称
                sw.Write(dr["IOPortName"]);
                //写入空格
                for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                sw.Write(": "+dr["IODirection"] + " ");
                //判断是否需要写入位宽信息
                // string isbus = dr["IOIsBus"].ToString();
                // Boolean isbusb = (Boolean)dr["IOIsBus"];
                if ((Boolean)dr["IOIsBus"]) sw.Write(dr["IOBusPart"]);
                else sw.Write("std_logic");
                //除最后一行外都加入分号
                if (wr_cnt < vhdlPortInfoTable.Rows.Count) sw.Write(";");
                //换行
                sw.Write("\n");

            }
            //写入port终止括号行
            sw.WriteLine(");");
            //写入end关键字行
            sw.WriteLine("end " + entityName + ";");
            sw.WriteLine("");
            return 0;
        }
        //2.写入component
        public int vhdlWriteComponent(StreamWriter sw, DataTable vhdlPortInfoTable, string entityName, int n_nameLenMax)
        {
            sw.WriteLine("--Definition of component");
            //写入entity，port关键字 行
            sw.WriteLine("component " + entityName + " is");
            sw.WriteLine("port (");
            int wr_cnt = 0;
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                //计算每行填入的空格数
                int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);

                wr_cnt = wr_cnt + 1;
                sw.Write("\t");
                //写入端口名称
               // sw.Write("signal ");
                sw.Write(dr["IOPortName"]);
                //写入空格
                for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                sw.Write(": " + dr["IODirection"] + " ");
                //判断是否需要写入位宽信息
                // string isbus = dr["IOIsBus"].ToString();
                // Boolean isbusb = (Boolean)dr["IOIsBus"];
                if ((Boolean)dr["IOIsBus"]) sw.Write(dr["IOBusPart"]);
                else sw.Write("std_logic");
                //除最后一行外都加入分号
                if (wr_cnt < vhdlPortInfoTable.Rows.Count) sw.Write(";");
                //换行
                sw.Write("\n");

            }
            //写入port终止括号行
            sw.WriteLine(");");
            //写入end关键字行
            sw.WriteLine("end component;");
            sw.WriteLine("");
            return 0;
        }
        //3.写入信号定义
        public int vhdlWriteSignal(StreamWriter sw, DataTable vhdlPortInfoTable, int n_nameLenMax)
        {
            
            
           //先写输入
            sw.WriteLine("--Definition of input signals");
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                if(dr["IODirection"].ToString().ToLower()=="in")
                {   //计算每行填入的空格数
                    int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);


                    sw.Write("\t");
                    //写入端口名称
                    sw.Write("signal ");
                    sw.Write(dr["IOPortName"]);
                    //写入空格
                    for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                    // sw.Write(": " + dr["IODirection"] + " ");
                    sw.Write(": ");
                    //判断是否需要写入位宽信息
                    // string isbus = dr["IOIsBus"].ToString();
                    // Boolean isbusb = (Boolean)dr["IOIsBus"];
                    if ((Boolean)dr["IOIsBus"]) sw.Write(dr["IOBusPart"]);
                    else sw.Write("std_logic");
                    sw.Write(";");

                    sw.Write("\n");
                }
            }
            //再写输出
            sw.WriteLine("--Definition of output signals");
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                if (dr["IODirection"].ToString().ToLower() == "out")
                {   //计算每行填入的空格数
                    int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);


                    sw.Write("\t");
                    //写入端口名称
                    sw.Write("signal ");
                    sw.Write(dr["IOPortName"]);
                    //写入空格
                    for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                    // sw.Write(": " + dr["IODirection"] + " ");
                    sw.Write(": ");
                    //判断是否需要写入位宽信息
                    // string isbus = dr["IOIsBus"].ToString();
                    // Boolean isbusb = (Boolean)dr["IOIsBus"];
                    if ((Boolean)dr["IOIsBus"]) sw.Write(dr["IOBusPart"]);
                    else sw.Write("std_logic");
                    sw.Write(";");

                    sw.Write("\n");
                }
            }
            //最后写inout
            sw.WriteLine("--Definition of inout signals");
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                if (dr["IODirection"].ToString().ToLower() == "inout")
                {   //计算每行填入的空格数
                    int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);


                    sw.Write("\t");
                    //写入端口名称
                    sw.Write("signal ");
                    sw.Write(dr["IOPortName"]);
                    //写入空格
                    for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                    // sw.Write(": " + dr["IODirection"] + " ");
                    sw.Write(": ");
                    //判断是否需要写入位宽信息
                    // string isbus = dr["IOIsBus"].ToString();
                    // Boolean isbusb = (Boolean)dr["IOIsBus"];
                    if ((Boolean)dr["IOIsBus"]) sw.Write(dr["IOBusPart"]);
                    else sw.Write("std_logic");
                    sw.Write(";");

                    sw.Write("\n");
                }
            }
            sw.WriteLine("");
            return 0;
        }
        //4.写入例化模板，可选择是否连接引脚
        public int vhdlWriteInstantiationTemplate(StreamWriter sw, DataTable vhdlPortInfoTable, string entityName, bool b_AddConnection, int n_nameLenMax)
        {
            sw.WriteLine("--Instantiation Template");
            int wr_cnt = 0;
            sw.WriteLine("my_inst_name :" + entityName);
            sw.WriteLine("port map(");
            foreach (DataRow dr in vhdlPortInfoTable.Rows)
            {
                //计算每行填入的空格数
                int n_spaceNeedCount = 4 + (n_nameLenMax - (int)dr["IOPortNameLength"]);

                wr_cnt = wr_cnt + 1;
                sw.Write("\t");
                //写入端口名称
                sw.Write(dr["IOPortName"]+" =>");
                //写入空格
                for (int spcCnt = 0; spcCnt < n_spaceNeedCount; spcCnt++) sw.Write(" ");
                sw.Write(dr["IOPortName"]);

                if (wr_cnt < vhdlPortInfoTable.Rows.Count) sw.Write(",");
                //换行
                sw.Write("\n");
               
            }
            //写入port终止括号行
            sw.WriteLine(");");
            return 0;
        }
        //5.写入tb
        public int vhdlWriteTestBench(StreamWriter sw)
        {
            sw.WriteLine("--TestBench Part");
            //写入固定单个时钟产生process
            sw.WriteLine("--Clock process definitions");
            List<string> clk_process_tmplt = new List<string>();
            clk_process_tmplt.Add("clk_process :process");
            clk_process_tmplt.Add("begin");
            clk_process_tmplt.Add("    clk <= '0';");
            clk_process_tmplt.Add("    wait for 10 ns; ");
            clk_process_tmplt.Add("    clk <= '1'; ");
            clk_process_tmplt.Add("    wait for 10 ns; ");
            clk_process_tmplt.Add("end process; ");

            foreach (string clk_line in clk_process_tmplt)
            {
                sw.WriteLine(clk_line);
            }


            //写入初始化process
            sw.WriteLine("--Initial process");
            sw.WriteLine("init_process :process");
            sw.WriteLine("begin");
            sw.WriteLine("\n\n\n\n\n");
            sw.WriteLine("end process;");
            return 0;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            bool temp_cheched = ((CheckBox)sender).Checked;
           
                switch (((CheckBox)sender).Text.ToString())
                {
                    case "module/entity+component": fileOutCfg.b_AddModuleOrEntityAndComponent = temp_cheched;
                        break;
                    case "信号定义": fileOutCfg.b_AddSignalDefinition = temp_cheched;
                        break;
                    case "例化模板": fileOutCfg.b_AddInstantiationTemplate = temp_cheched;
                                    if (temp_cheched == false) checkBox5.Checked = false;
                        break;
                    case "TestBench": fileOutCfg.b_AddTestBench = temp_cheched;
                                        
                        break;
                    case "例化模板填入同名信号": fileOutCfg.b_InsertSameNameSignal = temp_cheched;
                        break;
                }
           
            
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
           /* textBox1_fileDir.SelectAll();
            if (textBox1_fileDir.SelectedText != "")

                Clipboard.SetDataObject(textBox1_fileDir.SelectedText); 
             */
            if (last_fileDir != "")               
                System.Diagnostics.Process.Start("explorer.exe", last_fileDir);

        }
        //以下加入状态机分析模块
/// <summary>
/// 
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
        private void button3_showFSM_Click(object sender, EventArgs e)
        {
            
            LoadFSMBlock();
            
        }
        public void ShowFSM()
        {
            LoadFSMBlock();

        
        }
        public void LoadFSMBlock()
        {
            string fileFilter = "Verilog Flile(*.v)|*.v";//|VHDL Flile(*.vhd)|*.vhd";
            string fileType;
            string filePath = openFile(fileFilter, out fileType);
            if (filePath == "err") return;
            List<string> list_str = new List<string>();
            list_str = loadFile(filePath);
            //把状态机定义添加到VerilogFSMState_localparam
            foreach (string ver_line in list_str)
            {
                string ver_line_regu;
                string[] verLineReguArry;
                if (ver_line.Contains("localparam"))
                {
                    //把制表符替换成空格，然后依据空格分割，最后获得状态机各状态名称
                    ver_line_regu = ver_line.Replace("\t", " ");
                    verLineReguArry = ver_line_regu.Split(' ');
                    VerilogFSMState_localparam.Add(verLineReguArry[1]);
                }
            }
            DataTable FSMSearchDataTable = CreateFSMSearchDataTable();
            DataRow dr;

            
           


            for (int lineNumber=1; lineNumber <= list_str.Count; lineNumber++)
            {
                foreach (string fsmName in VerilogFSMState_localparam)
                {
                    //列表索引从0开始，但是行号从1开始
                    string lineContent = list_str[lineNumber-1];
                    string lineContentPure = lineContent.Replace("\t"," ");
                    lineContentPure = lineContentPure.Replace(" ","");
                    //寻找case入口
                    if (lineContentPure.Contains(fsmName + ':'))
                    {
                        dr = FSMSearchDataTable.NewRow();
                        dr["FSMName"] = fsmName;
                        dr["lineNumber"] = lineNumber;
                        FSMSearchDataTable.Rows.Add(dr);
                        


                    }

                }

            }
            //针对最后一个状态添加一个结束行号项
            int lastRowNum = FSMSearchDataTable.Rows.Count-1;
            int start_lineNumH = (int)FSMSearchDataTable.Rows[lastRowNum]["lineNumber"];
            int beginCount = 0;
            for (int lineNum = start_lineNumH ;
                lineNum < list_str.Count;
                lineNum++)
            {
                string lineContent = list_str[lineNum];
                lineContent = lineContent.Replace("\t", " ");
               
                if (lineContent.Contains("begin") )
                {
                    beginCount += 1;
                
                }
                else if (lineContent.Contains("end") &&
                         !lineContent.Contains("endcase")&&
                         !lineContent.Contains("endmodule")
                    )
                {
                    beginCount -= 1;
                    if (beginCount == 0)
                    {
                        dr = FSMSearchDataTable.NewRow();
                        dr["FSMName"] = "last";
                        dr["lineNumber"] = lineNum;
                        FSMSearchDataTable.Rows.Add(dr);
                        break;
                    }
                
                }
               // Form2_ShowFSM.Instance.richTextBox1.Text += lineContent+" " +beginCount.ToString() + "\n";
                
            }
            //获取每个状态的可能后继状态
            Dictionary<string, List<string>> stateNextState_dic = new Dictionary<string, List<string>>(); 
            //遍历行号表
            for (int i = 0; i < FSMSearchDataTable.Rows.Count-1 ; i++) //
            {
                List<string> nextStateArry = new List<string>();
                
                //遍历一个state case所在的行
                int start_lineNum = (int)FSMSearchDataTable.Rows[i]["lineNumber"];
                int end_lineNum = (int)FSMSearchDataTable.Rows[i + 1]["lineNumber"];
                
                for (int lineNum = start_lineNum + 1;
                    lineNum < end_lineNum;
                    lineNum++)
                { 
                    //在这些行中寻找state名称
                    foreach (string fsmName in VerilogFSMState_localparam)
                    {
                        if (list_str[lineNum-1].Contains(fsmName))
                        {
                            nextStateArry.Add( fsmName);
                            Console.WriteLine(fsmName);
                            
                        }
                    }
                    
                    
                
                }
               
                if (nextStateArry.Count > 0)
                {
                    string key = FSMSearchDataTable.Rows[i]["FSMName"].ToString();
                    
                    stateNextState_dic.Add(key, nextStateArry);
                }
            
            }//遍历行号表结束

            //开始绘制状态图
            //Form2_ShowFSM.Instance.placeStateCells(stateNextState_dic);
            foreach (string key in stateNextState_dic.Keys)
            {
                TreeNode node = new TreeNode();
                
                node.Text = key;
                
                List<string> stateList = stateNextState_dic[key];
                for (int i = 0; i < stateList.Count; i++)
                {
                    TreeNode childNode = new TreeNode();
                    childNode.Text = stateList[i];
                    node.Nodes.Add(childNode);
                }
                Form2_ShowFSM.Instance.treeView1.Nodes.Add(node);


            
            }
            
            
             
            
        
        }

        public DataTable CreateFSMSearchDataTable()
        {
            DataTable FSMSearchDataTable = new DataTable();

            DataColumn FSMName = new DataColumn("FSMName");
            DataColumn lineNumber = new DataColumn("lineNumber");

            FSMName.DataType = Type.GetType("System.String");
            lineNumber.DataType = Type.GetType("System.Int32");

            FSMSearchDataTable.Columns.Add(FSMName);
            FSMSearchDataTable.Columns.Add(lineNumber);

            return FSMSearchDataTable;       
        }

        private void fSM分析ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }



    }//form
}
